/**   
* @Title: WebAppConfigurer.java
* @Package org.xaoyaoyao.cloud.web.config
* @Description: TODO
* @author xaoyaoyao
* @date Feb 11, 2019 2:22:16 PM
* @version V1.0   
*/
package org.xaoyaoyao.cloud.web.config;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.xaoyaoyao.cloud.web.interceptor.FrequencyHandlerInterceptor;
import org.xaoyaoyao.cloud.web.interceptor.WebInterceptor;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer;

import lombok.extern.slf4j.Slf4j;
import springfox.documentation.spring.web.json.Json;

/**
 * @ClassName: WebAppConfigurer
 * @Description: TODO
 * @author xaoyaoyao
 * @date Feb 11, 2019 2:22:16 PM
 * 
 */
@Slf4j
@Configuration
public class WebAppConfigurer extends WebMvcConfigurationSupport {

	/** 解决跨域问题 **/
	@Override
	public void addCorsMappings(CorsRegistry registry) {
		super.addCorsMappings(registry);
	}

	/** 添加拦截器 **/
	@Override
	protected void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new WebInterceptor());
		registry.addInterceptor(new FrequencyHandlerInterceptor());
		super.addInterceptors(registry);
	}

	/** 这里配置视图解析器 **/
	@Override
	protected void configureViewResolvers(ViewResolverRegistry registry) {
		super.configureViewResolvers(registry);
	}

	/** 配置内容裁决的一些选项 **/
	@Override
	protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
		super.configureContentNegotiation(configurer);
	}

	/** 视图跳转控制器 **/
	@Override
	protected void addViewControllers(ViewControllerRegistry registry) {
		super.addViewControllers(registry);
	}

	/** 静态资源处理 **/
	@Override
	protected void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/").addResourceLocations("classpath:/templates/")
				.addResourceLocations("classpath:/resources/").addResourceLocations("classpath:/public/");
		registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
		registry.addResourceHandler("/swagger-resources/**").addResourceLocations("classpath:/META-INF/swagger-resources/");
		super.addResourceHandlers(registry);
	}

	/** 默认静态资源处理器 **/
	protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		super.configureDefaultServletHandling(configurer);
		configurer.enable();
	}

	@Bean
	public HttpMessageConverters fastJsonHttpMessageConverters() {
		return new HttpMessageConverters(getFastJsonHttpMessageConverter());
	}

	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		super.configureMessageConverters(converters);
		Iterator<HttpMessageConverter<?>> iterator = converters.iterator();
		while (iterator.hasNext()) {
			HttpMessageConverter<?> converter = iterator.next();
			if (converter instanceof MappingJackson2HttpMessageConverter) {
				log.info(">>>>>>>> remove the MappingJackson2HttpMessageConverter!");
				iterator.remove();
			}
		}
		converters.add(getFastJsonHttpMessageConverter());
	}

	private FastJsonHttpMessageConverter getFastJsonHttpMessageConverter() {
		// 1、需要先定义一个 convert 转换消息的对象
		FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
		// 2、创建Fastjosn对象并设定序列化规则
		FastJsonConfig fastJsonConfig = new FastJsonConfig();
		// SerializerFeature.WriteNonStringValueAsString导致Swagger2-ui无法显示UI
		fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteNullListAsEmpty,
				SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteNullBooleanAsFalse,
				SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteEnumUsingToString);
		// 3、中文乱码解决方案
		List<MediaType> mediaTypes = new ArrayList<MediaType>();
		// 设定json格式且编码为UTF-8
		mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
		fastConverter.setSupportedMediaTypes(mediaTypes);
		// Swagger2与FastJson兼容问题
		fastJsonConfig.getSerializeConfig().put(Json.class, SwaggerJsonSerializer.instance);
		// 4、规则赋予转换对象
		fastConverter.setFastJsonConfig(fastJsonConfig);
		return fastConverter;
	}
}
